package com.cx.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cx.entity.DTO.UserDTO;
import com.cx.entity.User;
import com.cx.mapper.UserMapper;
import com.cx.service.IUserService;
import com.cx.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cx
 * @since 2024-06-07
 */

@com.alibaba.dubbo.config.annotation.Service //：发布接口服务
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private UserMapper userMapper;

    @Override
    public IPage<User> getUserListPageConditions(Map<String, Object> params) {
        IPage<User> page = new Page<>(Integer.parseInt((String) params.get("page")), Integer.parseInt((String) params.get("limit")));
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        Map<String, String> paramsMap = null;
        if (params.get("searchParams") != null) {
            String startDate = null,
                    endDate = null;
//          将获取的json格式的字符串转为Java中的对象
            paramsMap = (Map) (JSON.parse((String) params.get("searchParams")));
//          切割日期字符串
            if (!"".equals(paramsMap.get("created"))) {
                startDate = (paramsMap.get("created").split("~"))[0];
                endDate = (paramsMap.get("created").split("~"))[1];
            }

            userLambdaQueryWrapper.eq(!"".equals(paramsMap.get("id")), User::getId, paramsMap.get("id"))
                    .like(!"".equals(paramsMap.get("username")), User::getUsername, paramsMap.get("username"))
                    .eq(!"".equals(paramsMap.get("rid")), User::getRid, paramsMap.get("rid"))
                    .between(!"".equals(paramsMap.get("created")), User::getCreated, startDate, endDate)
            ;
        }
        return this.baseMapper.getUserListPageConditions(page, userLambdaQueryWrapper);
    }

    @Override
    public R userLogin(Map<String, Object> person) {
        // 获取预期用户名是唯一结果，使用 selectOne,如果没有找到，selectOne 会返回 null.得到唯一的user后查询getPassword进行判断成功则登录否则出错
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, person.get("username")));
        if (user == null) {
            return R.error(401, "用户不存在");
        }
        // 检查密码和rid是否匹配
        if (!user.getPassword().equals(person.get("password")) || !user.getRid().equals(person.get("rid"))) {
            return R.error(401, "账户密码错误,权限错误");
        }

        //判断是否读取到redis缓存数据
        boolean flagRedis = true;
        try {//尝试从Redis获取数据信息,测试使用 redisTemplate
            R o = (R) redisTemplate.opsForValue().get("username:" + user.getUsername() + user.getId() + "_rid:" + user.getRid());
            if (o != null) {
                System.out.println("成功，从Redis缓存读取到数据");
                return o;
            }
        } catch (RedisConnectionFailureException e) {
            flagRedis = false;
            // 处理Redis连接失败的情况，这里选择忽略异常并继续执行
            System.out.println("Redis不可用，无法访问Redis，尝试直接处理登录成功逻辑");
        }


        if (user.getPassword().equals(person.get("password")) && user.getRid().equals(person.get("rid"))) {
            //将user转化为userDTO对象
            R r = R.ok(0, "登录成功").put("data", convertToDTO(user));
            if (r != null) {
                if (flagRedis){
                    try {
                        redisTemplate.opsForValue().set("username:" + user.getUsername() + user.getId() + "_rid:" + user.getRid(), r);
                        System.out.println("成功，读取数据库数据存储到Redis缓存中");
                    } catch (RedisConnectionFailureException e) {
                        System.out.println("查询的数据存储到Redis失败");
                    }
                }
                return r;
            }
        }
        return R.error(500, "数据异常");
    }

    //打赏对方
    @Override
    @Transactional // 声明该方法在一个事务上下文中执行
    public int RewardMoneyUpdate(Integer id, Integer pId, Float money) {
        User user=userMapper.selectById(id);

        user.setMoney(user.getMoney()-10);
        userMapper.updateById(user);
        System.out.println("user = " + user);

        User pUser=userMapper.selectById(pId);
        System.out.println("pUser ========= " + pUser);
        pUser.setMoney(pUser.getMoney()+10);
        return userMapper.updateById(pUser);
    }

    // 将User转换为UserDTO
    private UserDTO convertToDTO(User user) {
        if (user == null) {
            return null;
        }
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        userDTO.setUsername(user.getUsername());
        userDTO.setRid(user.getRid());
        return userDTO;
    }
}
